package com.wl.cloud.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.wl.cloud.core.dto.DataStoreDTO;
import com.wl.cloud.core.utils.PageUtils;
import com.wl.cloud.system.dao.SysRoleMapper;
import com.wl.cloud.system.dao.SysUserRoleMapper;
import com.wl.cloud.system.domain.SysRole;
import com.wl.cloud.system.domain.SysUserRole;
import com.wl.cloud.system.service.SysUserRoleService;
import com.wl.cloud.system.support.dto.SysUserRoleDTO;
import com.wl.cloud.system.support.dto.query.SysUserRoleQueryDTO;
import com.wl.cloud.system.support.vo.SysUserRoleVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户角色表 服务实现类
 *
 * @author wanglin
 * @since 2023-09-18
 */
@Service
public class SysUserRoleServiceImpl implements SysUserRoleService {

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private SysRoleMapper roleMapper;

    @Transactional(readOnly = true)
    @Override
    public DataStoreDTO<SysUserRoleVO> page(Pageable pageable, SysUserRoleQueryDTO queryDto) {
        QueryWrapper<SysUserRole> queryWrapper = this.buildQuery(queryDto);
        Page<SysUserRole> page = PageUtils.transferPage(pageable);
        Page<SysUserRole> result = this.sysUserRoleMapper.selectPage(page, queryWrapper);
        return new DataStoreDTO(result.getTotal(), this.transferVo(result.getRecords()));
    }

    @Transactional(readOnly = true)
    @Override
    public List<SysUserRoleVO> list(Sort sort, SysUserRoleQueryDTO queryDto) {
        QueryWrapper<SysUserRole> queryWrapper = this.buildQuery(queryDto);
        PageUtils.transferSort(queryWrapper, sort);
        return this.transferVo(this.sysUserRoleMapper.selectList(queryWrapper));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(SysUserRoleDTO dto) {
        // TODO 唯一性字段校验
        dto.setId(null);
        sysUserRoleMapper.insert(this.transferEntity(null, dto));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(SysUserRoleDTO dto) {
        Assert.hasText(dto.getId(), "id不能为空");
        // TODO 唯一性字段校验
        SysUserRole entity = sysUserRoleMapper.selectById(dto.getId());
        Assert.notNull(entity, "找不到id为 " + dto.getId() + " 的记录");
        sysUserRoleMapper.updateById(this.transferEntity(entity, dto));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Set<String> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            sysUserRoleMapper.deleteBatchIds(ids);
        }
    }

    @Transactional(readOnly = true)
    @Override
    public SysUserRoleVO get(String id) {
        Assert.hasText(id, "id不能为空");
        SysUserRole entity = sysUserRoleMapper.selectById(id);
        Assert.notNull(entity, "找不到id为 " + id + " 的记录");
        return this.transferVo(entity);
    }

    @Transactional(readOnly = true)
    @Override
    public List<String> getRoleIdsByUserId(String userId) {
        if (StringUtils.isBlank(userId)) {
            return Lists.newArrayList();
        }
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserRole::getUserId, userId);
        List<SysUserRole> userRoleList = sysUserRoleMapper.selectList(queryWrapper);
        if (org.springframework.util.CollectionUtils.isEmpty(userRoleList)) {
            return Lists.newArrayList();
        }
        return userRoleList.stream().map(e -> e.getRoleId()).collect(Collectors.toList());
    }

    @Transactional(readOnly = true)
    @Override
    public String getAuthoritiesByUserId(String userId) {
        //用户具有的角色id
        List<String> roleIdList = getRoleIdsByUserId(userId);
        String authorities = "";
        if (CollUtil.isNotEmpty(roleIdList)) {
            List<SysRole> roleList = roleMapper.selectBatchIds(roleIdList);
            Assert.notEmpty(roleList, "用户对应的角色不存在");
            //获取拥有的角色的code
            authorities = roleList.stream().map(e -> e.getCode()).collect(Collectors.joining(StringPool.COMMA));
        }
        return authorities;
    }

    @Transactional(readOnly = true)
    @Override
    public List<SysUserRole> getListByRoleIds(Set<String> roleIds) {
        if (CollectionUtils.isEmpty(roleIds)) {
            return Lists.newArrayList();
        }
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(SysUserRole::getRoleId, roleIds);
        return sysUserRoleMapper.selectList(queryWrapper);
    }

    @Transactional(readOnly = true)
    @Override
    public void deleteByUserIds(Set<String> userIds) {
        if (!org.springframework.util.CollectionUtils.isEmpty(userIds)) {
            //根据用户主键id，获取该用户所拥有的角色集合，userRole
            QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().in(SysUserRole::getUserId, userIds);
            sysUserRoleMapper.delete(queryWrapper);
        }
    }

    private QueryWrapper<SysUserRole> buildQuery(SysUserRoleQueryDTO queryDto) {
        QueryWrapper<SysUserRole> queryWrapper = new QueryWrapper<>();
        if (Objects.nonNull(queryDto)) {
            queryWrapper.lambda().eq(StringUtils.isNotBlank(queryDto.getId()), SysUserRole::getId, queryDto.getId());
        }
        return queryWrapper;
    }

    private SysUserRole transferEntity(SysUserRole entity, SysUserRoleDTO dto) {
        if (Objects.isNull(entity)) {
            entity = new SysUserRole();
        }
        BeanUtils.copyProperties(dto, entity);
        return entity;
    }

    private List<SysUserRoleVO> transferVo(List<SysUserRole> entities) {
        if (CollectionUtils.isEmpty(entities)) {
            return Lists.newArrayList();
        }

        List<SysUserRoleVO> voList = entities.stream().map(entity -> {
            SysUserRoleVO vo = new SysUserRoleVO();
            BeanUtils.copyProperties(entity, vo);
            return vo;
        }).collect(Collectors.toList());
        return voList;
    }

    private SysUserRoleVO transferVo(SysUserRole entity) {
        if (Objects.isNull(entity)) {
            return null;
        }
        SysUserRoleVO vo = new SysUserRoleVO();
        BeanUtils.copyProperties(entity, vo);
        return vo;
    }
}
